﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using RAP.Framework.Libary.Utils;
using System.Xml;
using static RAP.Framework.Libary.DomTemplateBuilder.Consts;
using RAP.Framework.Libary.DomTemplateBuilder.Configuration;
using RAP.Framework.Libary.DomTemplateBuilder.ContentRender;
using System.Threading;

namespace RAP.Framework.Libary.DomTemplateBuilder.Element
{
	/// <summary>
	/// 文档模板节点基类
	/// </summary>
	public abstract class ElementBase : Hashtable, IElement, IContextElement, IDisposable
    {
		private static long _identityCounter = 0;

        public ElementBase ()
        {
			this.Id = Interlocked.Increment( ref _identityCounter );
			this.ChildNodes = new List<ElementBase>();
        }

		#region 属性

		public long Id { get; private set; }

        /// <summary>
        /// 节点所属文档模板Template对象
        /// </summary>
        public virtual TemplateItem Template { get; set; }

        /// <summary>
        /// 子节点集合
        /// </summary>
        public virtual IList<ElementBase> ChildNodes { get; set; }

        /// <summary>
        /// 父节点
        /// </summary>
        public virtual IElement Parent { get; set; }

        private IContentRender _contentRender = null;
        /// <summary>
        /// 解析文本内容的正则表达式
        /// </summary>
		public virtual IContentRender ContentRender
        {
            get
            {
                if ( _contentRender == null )
                {
                    lock ( this )
                    {
                        if ( _contentRender == null )
                        {
                            string patternRender = this.ToString( Consts.CONTENT_RENDER_FIELD );
                            if ( string.IsNullOrEmpty( patternRender ) )
                            {
                                if ( this.Parent != null )
                                {
                                    if ( this.Parent is ElementBase )
                                    {
                                        _contentRender = ( this.Parent as ElementBase ).ContentRender;
                                    }
                                }
                                if ( _contentRender == null )
                                {
                                    if ( this.Template != null )
                                    {
                                        _contentRender = this.Template.ContentRender;
                                    }
                                }
                                if ( _contentRender == null )
                                {
                                    _contentRender = DomTemplateManager.DefaultContentRender;
                                }
                            }
                            else
                            {
                                _contentRender = DomTemplateManager.GetContentRender( patternRender.Trim() );
                            }
                        }
                    }
                }
                return _contentRender;
            }
            set
            {
                _contentRender = value;
            }
        }

        protected PropertyValueStyles? _valueStyle;
        /// <summary>
        /// 属性的来源类型（根参数对象、上下文对象）
        /// </summary>
        public virtual PropertyValueStyles ValueStyle
        {
            get
            {
                if ( _valueStyle == null )
                {
                    _valueStyle = this.ToString( VALUE_STYLE_FIELD ).ToEnumValue<PropertyValueStyles>( PropertyValueStyles.NotSet );
                }
                return _valueStyle.Value;
            }
            set
            {
                _valueStyle = value;
            }
        }

        /// <summary>
        /// 对应处理节点类型的名称
        /// </summary>
        public virtual string HandlerName
        {
            get
            {
                return this.ToString( HANDLER_NAME_FIELD );
            }
            set
            {
                //如果设置了自定义的Handler名称，则清空_handlerType对象
                this[ HANDLER_NAME_FIELD ] = value;
                this._handlerType = null;
            }
        }

        private Type _handlerType = null;
        /// <summary>
        /// 对应Handler节点的类型
        /// </summary>
        public virtual Type HandlerType
        {
            get
            {
                if ( _handlerType == null )
                {
                    _handlerType = this.Template.DomTemplate.GetHandlerType( this.HandlerName );
                }
                return _handlerType;
            }
            set
            {
                _handlerType = value;
            }
        }

        private IHandler _handler = null;
        /// <summary>
        /// 获取当前节点对应的Handler
        /// </summary>
        public virtual IHandler Handler
        {
            get
            {
                if ( _handler != null )
                {
                    return _handler;
                }
                if ( this.HandlerType == null )
                {
                    return null;
                }
                _handler = this.HandlerType.Assembly.CreateInstance( this.HandlerType.FullName ) as IHandler;
                _handler.Element = this;
                return _handler;
            }
            set
            {
                _handler = value;
            }
        }
        #endregion

        /// <summary>
        /// 初始化，并转换XML配置节点
        /// </summary>
        /// <param name="node"></param>
        public virtual void Initialize ( XmlNode node )
        {
            this.ParseXMLAttributes( node );
            this.Parent.ChildNodes.Add( this );
        }

        /// <summary>
        /// 获取XML的属性
        /// </summary>
        /// <param name="node"></param>
        protected virtual void ParseXMLAttributes ( XmlNode node )
        {
            node.Attributes.ToDictionary( this );
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public virtual void Dispose ()
        {
            foreach ( IDisposable ele in this.ChildNodes )
            {
                ele.Dispose();
            }
            this.Template = null;
            this.ChildNodes.Clear();
            this.ChildNodes = null;
            this.Parent = null;
            if ( _handler != null )
            {
                _handler.Dispose();
            }
            _contentRender = null;
            _handler = null;
            _handlerType = null;
        }
    }
}
